package cn.middle.basic.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.middle.common.base.mapper.BaseMapper;
import com.middle.common.base.service.impl.BaseServiceImpl;
import com.middle.common.result.Page;

import cn.middle.basic.entity.SysMenu;
import cn.middle.basic.mapper.SysMenuMapper;
import cn.middle.basic.service.SysMenuService;
import cn.middle.basic.vo.MenuVo;

@Service
public class SysMenuServiceImpl extends BaseServiceImpl<SysMenu> implements SysMenuService {
	
	@Autowired
	private SysMenuMapper sysMenuMapper;

	@Override
	public List<SysMenu> selectMenuByUserId(Long userId) {
		return sysMenuMapper.selectMenuByUserId(userId);
	}

	@Override
	public List<String> selectAuthorisationCodeByUserId(Long userId) {
		return sysMenuMapper.selectAuthorisationCodeByUserId(userId);
	}

	@Override
	public BaseMapper<SysMenu> getDao() {
		return sysMenuMapper;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Page<SysMenu> list(int page, int pageSize, String name) {
		PageHelper.startPage(page,pageSize);
		List<SysMenu> menus = sysMenuMapper.selectByName(name);
		return new Page(new PageInfo<SysMenu>(menus));
	}

	@Override
	public List<SysMenu> selectByPid(Long pId) {
		return sysMenuMapper.selectByPid(pId);
	}

	@Override
	public List<MenuVo> listVo(String name) {
		List<SysMenu> menus = sysMenuMapper.selectByName(name);
		return analysisRelation(menus);
	}
	
	private List<MenuVo> analysisRelation(List<SysMenu> in){
		List<MenuVo> menuVos = new ArrayList<>();
		in.forEach(obj -> menuVos.add(vo(obj)));
		
		List<MenuVo> rootVos = new ArrayList<>();
		menuVos.forEach(action -> {
			if(action.getParentId() == null) {
				rootVos.add(action);
			}
		});
		
		rootVos.forEach(action ->{
			List<MenuVo> children = new ArrayList<>();
			findChildren(action,menuVos,children);
			if(!children.isEmpty()) {
				action.setChildren(children);
			}
		});
		
		return rootVos;
	}
	
	
	/**
	 * 递归获取菜单树
	 * @param vo
	 * @param vos
	 * @param children
	 */
	private void findChildren(MenuVo vo,List<MenuVo> vos,List<MenuVo> children) {
		
		vos.forEach(action -> {
			if(action.getParentId() != null && action.getParentId().longValue() == vo.getId().longValue()) {
				children.add(action);
				List<MenuVo> childrenList = new ArrayList<>();
				findChildren(action,vos,childrenList);
				if(!childrenList.isEmpty()) {
					action.setChildren(childrenList);
				}
			}
		});
	}
	
	private MenuVo vo(SysMenu menu) {
		MenuVo vo = new MenuVo();
		vo.setId(menu.getId());
		vo.setIcon(menu.getIcon());
		vo.setName(menu.getName());
		vo.setCreateTime(menu.getCreateTime());
		vo.setParentId(menu.getParentId());
		vo.setComponent(menu.getComponent());
		vo.setSort(menu.getSort());
		vo.setAuthorisationCode(menu.getAuthorisationCode());
		vo.setStatus(menu.getStatus());
		return vo;
	}

	@Override
	public List<SysMenu> list(String name) {
		return sysMenuMapper.selectByName(name);
	}

	@Override
	public List<SysMenu> menuTypeList(Byte menuType) {
		return sysMenuMapper.selectByMenuType(menuType);
	}

	@Override
	public void deleteParentId(Long parentId) {
		sysMenuMapper.deleteByParentId(parentId);
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void deleteBySysId(Long id) {
		loopDelete(id);
	}
	
	private void loopDelete(Long id) {
		List<SysMenu> childs = sysMenuMapper.selectByPid(id); //获取子菜单
		for(SysMenu child : childs) {
			loopDelete(child.getId()); //循环先删除子菜单
		}
		this.sysMenuMapper.deleteByPrimaryKey(id);
	}
}
